package com.alibaba.citrus.ots.forecast.functions.forecastorder.entity;

import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.model.ApiContext;
import com.alibaba.citrus.ots.common.util.CalendarCompareUtil;
import com.alibaba.citrus.ots.common.util.SpringContextUtil;
import com.alibaba.citrus.ots.forecast.common.LogUtils;
import com.alibaba.citrus.ots.forecast.functions.forecastorder.ability.PriceQueryUtils;
import com.alibaba.citrus.ots.forecast.functions.forecastorder.constants.ForecastConstants;
import com.alibaba.citrus.ots.forecast.repository.*;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.db.service.CustomSequenceAccessor;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.lattice2.epoch.user.dto.LoginUser;
import com.alibaba.lattice2.epoch.user.service.EpochLoginUserService;
import com.epoch.app.bcots.model.dto.EmployeeGetCurrentLoginResponse;
import com.epoch.app.bcots.model.dto.QueryWarehouseByIdRequest;
import com.epoch.app.bcots.model.dto.WarehouseInfo;
import com.epoch.app.bcots.platform_enhance.SaleOrderTag;
import com.epoch.app.bcots.service.BcOtsService;
import com.epoch.app.bcots.service.UnifiedInventoryService;
import com.epoch.app.otsforecastsales.api.forecastorderwrite.dto.DeleteActivityForecastRequest;
import com.epoch.app.otsforecastsales.api.forecastorderwrite.service.ForecastOrderWriteService;
import com.epoch.app.otsforecastsales.domian.deallinequeue.model.DealLineQueue;
import com.epoch.app.otsforecastsales.dto.request.ConfirmForecastRequest;
import com.epoch.app.otsforecastsales.dto.response.ConfirmForecastResponse;
import com.epoch.app.otsforecastsales.enums.ForecastLineStatusEnum;
import com.epoch.app.otsforecastsales.enums.ForecastStatusEnum;
import com.epoch.app.otsforecastsales.model.dto.ActivitySDO;
import com.epoch.app.otsforecastsales.model.dto.DealLineSDO;
import com.epoch.app.otsforecastsales.model.dto.GiftSDO;
import com.epoch.app.otsforecastsales.model.dto.QueryAvailableInventoryRequest;
import com.epoch.app.otsforecastsales.model.enums.ForecastDealStatusSEO;
import com.epoch.app.otsforecastsales.model.enums.ForecastDealTypeSEO;
import com.epoch.app.otsforecastsales.model.enums.ForecastOrderLogEnum;
import com.epoch.app.otsforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.otsforecastsales.sdo.ForecastOrderSDO;
import com.epoch.app.otsplatformenhance.api.scitemquery.service.ScItemQueryService;
import com.epoch.app.otsplatformenhance.api.strategyquery.service.StrategyQueryService;
import com.epoch.app.otsplatformenhance.domain.scitemunit.dto.ScItemUnitLoadListRequest;
import com.epoch.app.otsplatformenhance.domain.scitemunit.model.ScItemUnit;
import com.epoch.app.otsplatformenhance.domain.scitemunit.service.ScItemUnitService;
import com.epoch.app.otsplatformenhance.dto.request.IdQueryRequest;
import com.epoch.app.otsplatformenhance.enums.StrategyTypeEnum;
import com.epoch.app.otsplatformenhance.inventoryallotlinewrite.dto.ReleaseAndDeductRequest;
import com.epoch.app.otsplatformenhance.inventoryallotlinewrite.service.InventoryAllotLineWriteService;
import com.epoch.app.otsplatformenhance.inventoryallotquery.service.InventoryAllotQueryService;
import com.epoch.app.otsplatformenhance.model.dto.*;
import com.epoch.app.otsplatformenhance.model.enums.RuleTypeEnum;
import com.epoch.app.otsplatformenhance.sdo.DimensionSDO;
import com.epoch.app.otsplatformenhance.sdo.StrategySDO;
import com.epoch.app.otspricecenter.api.activityquery.service.ActivityQueryService;
import com.epoch.app.otspricecenter.api.activitywrite.service.ActivityWriteService;
import com.epoch.app.otspricecenter.dto.request.*;
import com.epoch.app.otspricecenter.dto.response.ActivityInfoResponse;
import com.epoch.app.otspricecenter.dto.response.ActivityTermResponse;
import com.epoch.app.otspricecenter.dto.response.ParticipateActivityInfoResponse;
import com.epoch.app.otspricecenter.dto.response.ParticipateInActivityResponse;
import com.epoch.app.otspricecenter.model.dto.ActivityResponse;
import com.epoch.app.otspricecenter.model.dto.ParticipateActivityRequest;
import com.epoch.app.otspricecenter.model.dto.QueryActivityRequest;
import com.epoch.app.otspricecenter.model.enums.ActivityTypeEnum;
import com.epoch.app.otsunifiedinventory.api.allocateorderwrite.service.AllocateOrderWriteService;
import com.epoch.app.otsunifiedinventory.dto.request.AllocateOrderManualCreateRequest;
import com.epoch.app.otsunifiedinventory.dto.request.AllocateOrderSaveRequest;
import com.epoch.app.otsunifiedinventory.dto.response.AllocateOrderResponse;
import com.epoch.app.otsunifiedinventory.dto.response.AllocateOrderSaveResponse;
import com.epoch.app.otsunifiedinventory.model.dto.AllocateOrderScItemDetail;
import lombok.Getter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author qianlei
 */
@Getter
public class ForecastOrderEntity {
    private static final Log log = Log.getLogger(ForecastOrderEntity.class);
    private ForecastOrderSDO forecastOrderSDO;

    public static final String ALLOTLINEID = "allotlineid";
    public static final String DISINTEGRATION_QTY = "disintegrationQty";

    private static ActivityQueryService activityQueryService = SpringContextUtil.getBean(ActivityQueryService.class);
    private static AllocateOrderWriteService allocateOrderWriteService = SpringContextUtil.getBean(AllocateOrderWriteService.class);
    private static StrategyQueryService strategyQueryService = SpringContextUtil.getBean(StrategyQueryService.class);
    private static ActivityWriteService activityWriteService = SpringContextUtil.getBean(ActivityWriteService.class);
    private static CustomSequenceAccessor customSequenceAccessor = SpringContextUtil.getBean(CustomSequenceAccessor.class);
    private static ScItemQueryService scItemQueryService = SpringContextUtil.getBean(ScItemQueryService.class);
    private static ForecastOrderWriteService forecastOrderWriteService = SpringContextUtil.getBean(ForecastOrderWriteService.class);
    private static ScItemUnitService scItemUnitService = SpringContextUtil.getBean(ScItemUnitService.class);
    private static PriceQueryUtils priceQueryUtils = SpringContextUtil.getBean(PriceQueryUtils.class);
    private static UnifiedInventoryService unifiedInventoryService=SpringContextUtil.getBean(UnifiedInventoryService.class);
    private static EpochLoginUserService epochLoginUserService;
    //处理队列写
    private static DealLineWriteRepository dealLineWriteRepository;
    //处理队列读
    private static DealLineQueryRepository dealLineQueryRepository;
    //主单读
    private static ForecastOrderQueryRepository forecastOrderQueryRepository;
    //主单写
    private static ForecastOrderWriteRepository forecastOrderWriteRepository;
    //子订单写
    private static ForecastOrderLineWriteRepository forecastOrderLineWriteRepository;
    //子订单读
    private static ForecastOrderLineQueryRepository forecastOrderLineQueryRepository;

    private static InventoryAllotQueryService inventoryAllotQueryService;

    private static InventoryAllotLineWriteService inventoryAllotLineWriteService;
    private static BcOtsService bcOtsService;

    static {
        dealLineWriteRepository = SpringContextUtil.getBean(DealLineWriteRepository.class);
        forecastOrderQueryRepository = SpringContextUtil.getBean(ForecastOrderQueryRepository.class);
        dealLineQueryRepository = SpringContextUtil.getBean(DealLineQueryRepository.class);
        forecastOrderWriteRepository = SpringContextUtil.getBean(ForecastOrderWriteRepository.class);
        forecastOrderLineWriteRepository = SpringContextUtil.getBean(ForecastOrderLineWriteRepository.class);
        forecastOrderLineQueryRepository = SpringContextUtil.getBean(ForecastOrderLineQueryRepository.class);
        inventoryAllotQueryService = SpringContextUtil.getBean(InventoryAllotQueryService.class);
        inventoryAllotLineWriteService = SpringContextUtil.getBean(InventoryAllotLineWriteService.class);
        bcOtsService = SpringContextUtil.getBean(BcOtsService.class);
        epochLoginUserService=SpringContextUtil.getBean(EpochLoginUserService.class);
    }

    /**
     * 内外码转换 key
     */
    private static String CODE_FLAG = "codeFlag";
    /**
     * 内外码转换 value
     */
    private static String INNER_CODE_TO_OUT_CODE = "inner_code_to_out_code";
    /**
     * 添加活动查询参数
     */
    private static String ADD_ACTIVITY_QUERY_PARAM = "addActivityQueryParam";
    /**
     * 预报订单号
     */
    private static String FORECAST_ORDER_BIZ_ID = "forecastOrderBizId";
    /**
     *
     * 行号
     */
    private static String  SERIAL_NUMBER="serialNumber";

    private static String INVENTORY_CHECK_FAIL = "库存不足不可以生成销售订单！";

    private static String ACTIVITY_OCCUPY_EXCEPTION = "异常情况活动占用失败！";

    public static ForecastOrderEntity of(ForecastOrderSDO forecastOrderSDO) {
        ForecastOrderEntity forecastEntity = new ForecastOrderEntity();
        forecastEntity.forecastOrderSDO = forecastOrderSDO;
        return forecastEntity;
    }

    /*
        创建并保存预报单 王成
     */
    public String save() {
        LoginUser loginUser = epochLoginUserService.getLoginUser();
        String orderId = "";
//        isBack = false;
        //判断当前状态是否可以提交
        if ((!ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())
                && ForecastStatusEnum.PARTIAL_REPLY.getNumValue().equals(forecastOrderSDO.getStatus()))) {
            throw new FunctionException("OTS-04-001-00-15-017");
        }
//        this.forecastOrderSDO.setStatus(1);//设置位为草稿状态
        if (StringUtils.isEmpty(forecastOrderSDO.getId())) {
            // 保存预报主单
            //判断是否有主单id 没有先创建主单 有主单id 就设置子单的mainOrderId 创建子单
            String nextStringSequence = customSequenceAccessor.getNextStringSequence("ots_forecast_sales", "forecastOrderId");
            forecastOrderSDO.setOrderBizId(nextStringSequence);
            forecastOrderSDO.setCreatorName(forecastOrderSDO.getModifierName());
            forecastOrderSDO.setCreatorId(forecastOrderSDO.getModifierId());
            //设置位为草稿状态
            forecastOrderSDO.setStatus(ForecastStatusEnum.DRAFT.getNumValue());
            orderId = forecastOrderWriteRepository.save(this.forecastOrderSDO);
            LogUtils.printOperateLog(orderId,ForecastOrderLogEnum.CREATE.getForecastOrderLogValue(),"创建预报订单",loginUser);

        } else {//有主单id
            /*ForecastOrderSDO dbForecastOrderSDO = forecastOrderQueryRepository.queyrDetail(forecastOrderSDO.getId());
            Integer syncVersion = dbForecastOrderSDO.getSyncVersion();

            if (this.forecastOrderSDO.getSyncVersion()==null||syncVersion!=this.forecastOrderSDO.getSyncVersion()){
                throw new FunctionException("OTS-04-001-15-026");
            }*/
            //获取当前登录人信息
            EmployeeGetCurrentLoginResponse currentLoginResponse = bcOtsService.employeeGetCurrentLogin();
            //待回复状态的保存需要效验有效性策略 20220217需求 待回复状态可以编辑(add by myw) 只有业务员角色才效验待回复状态的有效性检查
            if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())&&currentLoginResponse.getOnlySales()){
                //判断待回复状态的订单是否可以保存
                //根据查询结果 判断是时间段还是截止时间 是拦截还是提示
                //如果是拦截的话不允许保存  提示的话可以保存
                MoreConditionQueryRequest moreConditionQueryRequest = new MoreConditionQueryRequest();
                moreConditionQueryRequest.setStrategyType(StrategyTypeEnum.VALIDITY.getCode());
                moreConditionQueryRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());//forecastOrderSDO.getOrganizationCode()
                moreConditionQueryRequest.setChannelCode(forecastOrderSDO.getChannelCode());//forecastOrderSDO.getChannelCode()
                moreConditionQueryRequest.setWareHouseCode(forecastOrderSDO.getWareHouseCode());
                log.info("ForecastOrderEntity|save|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|request|", JSONObject.toJSONString(moreConditionQueryRequest));
                Result<MoreConditionQueryResponse> moreConditionQueryResponseResult = strategyQueryService.moreConditionQuery(moreConditionQueryRequest);
                log.info("ForecastOrderEntity|save|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|result|", JSONObject.toJSONString(moreConditionQueryResponseResult));
                MoreConditionQueryResponse moreConditionQueryResponse = moreConditionQueryResponseResult.getResult();

                if (Objects.nonNull(moreConditionQueryResponse)) {
                    StrategySDO strategySDO = moreConditionQueryResponse.getStrategySDO();
                    List<DimensionSDO> dimensionSDOList = strategySDO.getDimensionSDOList();
                    DimensionSDO dimensionSDO = dimensionSDOList.get(0);
                    //获取规则
                    String value = dimensionSDO.getRuleName();
                    if (StringUtils.equals(RuleTypeEnum.TIME_POINT.getCode(), value)) {
                        //获取规则值
                        String ruleValue = dimensionSDO.getRuleValue();
                        //判断截止时间是否满足 当前时间大于截止时间 不满足
                        boolean compare = CalendarCompareUtil.compareDateTimes(null, ruleValue);
                        if (compare) {
                            Boolean executeAction = dimensionSDO.getExecuteAction();
                            if (executeAction) {
                                throw new FunctionException("OTS-04-001-00-15-048","该时间范围内不允许修改，请联系订单员修改");
                                // return "该时间范围内不允许修改，请联系订单员修改";
                            }
                        }
                    }
                    if (StringUtils.equals(RuleTypeEnum.TIME_FRAME.getCode(), value)) {
                        String ruleValue = dimensionSDO.getRuleValue();
                        //String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]") - 1).replace("\"", "");
                        String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]") ).replace("\"", "");
                        String[] split = substring.split(",");
    /*String ruleValueSplit = split[0].split(" ")[1];
    String ruleValueSplit1 = split[1].split(" ")[1];*/

                        String ruleValueSplit = split[0];
                        String ruleValueSplit1 = split[1];
                        boolean compareDateTimes = CalendarCompareUtil.compareDateTimes(ruleValueSplit, ruleValueSplit1);
                        //如果为true满足可以提交
                        if (!compareDateTimes) {
                            Boolean executeAction = dimensionSDO.getExecuteAction();
                            if (executeAction) {
                                throw new FunctionException("OTS-04-001-00-15-048","该时间范围内不允许修改，请联系订单员修改");
                                // return "该时间范围内不允许修改，请联系订单员修改";
                            }
                        }
                    }
                }
            }
            // todo   预报单乐观锁版本控制
            forecastOrderWriteRepository.modify(this.forecastOrderSDO);
            LogUtils.printOperateLog(this.forecastOrderSDO.getId(),ForecastOrderLogEnum.EDIT.getForecastOrderLogValue(),"编辑预报订单",loginUser);
            Integer num = 0;//行号
            //根据scitemId去重
            List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
            forecastOrderLineSDOList = forecastOrderLineSDOList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
                    -> new TreeSet<>(Comparator.comparing(ForecastOrderLineSDO::getScItemId))), ArrayList::new));
            //判断商品是否有重复
            Map<Object, Long> collect2 = forecastOrderLineSDOList.stream().collect(
                    Collectors.groupingBy(ForecastOrderLineSDO::getScItemId, Collectors.counting()));
            //筛出有重复的商品名称
            List<Object> collect3 = collect2.keySet().stream().
                    filter(key -> collect2.get(key) > 1).collect(Collectors.toList());
            if (collect3.size() > 0) {
                throw new FunctionException("OTS-04-001-00-15-014");
            }
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                if (forecastOrderLineSDO.getUnitPrice() == null){
                    throw new FunctionException("OTS-04-001-00-15-022");
                }
                //判断单价价格是否有负值
                if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())) {
                    if ( forecastOrderLineSDO.getUnitPrice() < 0L) {
                        throw new FunctionException("OTS-04-001-00-15-022");
                    }
                }

                // todo 价格校验按0303需求，后移至预报单提交
                //判断是不是新增的子单 老的子单更新 新的子单创建
                if (null != forecastOrderLineSDO.getId()) {
                    //add by myw,适配小程序传递过来features无值，影响每日库存分解回补和重新占用
                    Long orderLineId = forecastOrderLineSDO.getId();
                    ForecastOrderLineSDO queryOrderLine = forecastOrderLineQueryRepository.query(String.valueOf(orderLineId));
                    Map lineFeatures = queryOrderLine.getFeatures();
                    forecastOrderLineSDO.setFeatures(lineFeatures);
                    Integer realDeductQuantity = 0;
                    if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())){
                        Map features = forecastOrderLineSDO.getFeatures();
                        if (MapUtils.isNotEmpty(features)
                                &&Objects.nonNull(features.get(ALLOTLINEID))
                                &&StringUtils.isNotBlank(String.valueOf(features.get(ALLOTLINEID)))
                                &&Objects.nonNull(features.get(DISINTEGRATION_QTY))

                        ){
                            ReleaseAndDeductRequest releaseAndDeductRequest = new ReleaseAndDeductRequest();
                            releaseAndDeductRequest.setAllotLineId(String.valueOf(features.get(ALLOTLINEID)));
                            releaseAndDeductRequest.setOldDeductQuantity(String.valueOf(features.get(DISINTEGRATION_QTY)));
                            releaseAndDeductRequest.setNewDeductQuantity(forecastOrderLineSDO.getQuantity());
                            Result<DailyInventoryDeductResponse> releaseAndDeduct = inventoryAllotLineWriteService.releaseAndDeduct(releaseAndDeductRequest);
                            if (Objects.isNull(releaseAndDeduct)||!releaseAndDeduct.isSuccess()){
                                throw new FunctionException("OTS-04-001-00-15-053","待回复状态释放并重新扣减每日库存失败!");
                            }
                            realDeductQuantity = new BigDecimal(releaseAndDeduct.getResult().getRealDeductQuantity()).intValue();
                            // features.put(DISINTEGRATION_QTY,realDeductQuantity);

                        }
                    }
                    if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())){
                        verifyDailyInv(forecastOrderLineSDO);
                    }
                    modifyForecastOrderLine(forecastOrderLineSDO,realDeductQuantity);
                } else {
                    if (ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue().equals(forecastOrderSDO.getStatus())){
                        queryAndDeduct(forecastOrderLineSDO);
                    }

                    if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())){
                        verifyDailyInv(forecastOrderLineSDO);
                    }

                    num = addForecastOrderLine(num, forecastOrderLineSDO);

                }
            }
            orderId = forecastOrderSDO.getId();
        }
        return orderId;
    }

    private void verifyDailyInv(ForecastOrderLineSDO forecastOrderLineSDO) {
        Map<String,Object> dailyInventory=queryDailyInv(forecastOrderSDO, forecastOrderLineSDO);
        if ((boolean) dailyInventory.getOrDefault("limitSwitch",false)){
            if (StringUtils.isNotBlank(String.valueOf(dailyInventory.get("dailyInventory")))){
                BigDecimal existInventory = new BigDecimal(String.valueOf(dailyInventory.get("dailyInventory"))).setScale(3, RoundingMode.DOWN);
                BigDecimal forecastQuantity = new BigDecimal(forecastOrderLineSDO.getQuantity()).setScale(3, RoundingMode.DOWN);
                if (forecastQuantity.compareTo(existInventory)>0){
                    throw new FunctionException("OTS-06-005-00-15-024", forecastOrderLineSDO.getGoodsCode(),existInventory.intValue());
                }
            }
        }
    }

    @NotNull
    private Integer addForecastOrderLine(Integer num, ForecastOrderLineSDO forecastOrderLineSDO) {

        //创建子单
        //判断是否存在同一货品
        ForecastOrderLineSDO tmp = new ForecastOrderLineSDO();
        tmp.setScItemId(forecastOrderLineSDO.getScItemId());
        tmp.setMainOrderId(forecastOrderSDO.getId());
        List<ForecastOrderLineSDO> sdoList = forecastOrderLineQueryRepository.queyrLineDetailList(tmp);
        if (CollectionUtils.isNotEmpty(sdoList)) {
            throw new FunctionException("OTS-04-001-00-15-014");
        }
        ForecastOrderSDO forecastOrderSDO = forecastOrderLineQueryRepository.queryByOrderId(this.forecastOrderSDO);
        List<Integer> integers = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList1 = forecastOrderSDO.getForecastOrderLineSDOList();
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDOList1)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO1 : forecastOrderLineSDOList1) {
                if (StringUtils.isNotEmpty(forecastOrderLineSDO1.getSerialNumber())) {
                    integers.add(Integer.valueOf(forecastOrderLineSDO1.getSerialNumber()));
                }
            }
        }
        if (CollectionUtils.isNotEmpty(integers)) {
            Integer integer = integers.stream().reduce(Integer::max).get();
            num = integer / 10;
        }
        //设置行号
        num++;
        Integer serialNumber = num * 10;
        forecastOrderLineSDO.setSerialNumber(serialNumber.toString());
        //设置位草稿状态
        if (Objects.nonNull(this.forecastOrderSDO.getWareHouseCode())) {
            forecastOrderLineSDO.setWarehouseArea(this.forecastOrderSDO.getWareHouseCode());
        }
        forecastOrderLineSDO.setCustomerCode(this.forecastOrderSDO.getCustomerCode());
        forecastOrderLineSDO.setStatus(forecastOrderSDO.getStatus());
        forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.WAITING_DEAL.getStatus());
        forecastOrderLineSDO.setMainOrderId(this.forecastOrderSDO.getId());
        forecastOrderLineSDO.setMainOrderBizId(forecastOrderSDO.getOrderBizId());
        forecastOrderLineSDO.setModifierName(forecastOrderSDO.getModifierName());
        forecastOrderLineSDO.setCreatorId(forecastOrderSDO.getModifierId());
        forecastOrderLineSDO.setCreatorName(forecastOrderSDO.getModifierName());
        //默认累计回复数量为0
        forecastOrderLineSDO.setActualTotalReplyAmount(0);

        //设置总金额
        if(StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity())&&Objects.nonNull(forecastOrderLineSDO.getUnitPrice())){
            forecastOrderLineSDO.setTotalFee(Long.parseLong(forecastOrderLineSDO.getQuantity())* forecastOrderLineSDO.getUnitPrice());
        }
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
            HashMap<String, Object> stringObjectHashMap =MapUtils.isEmpty(forecastOrderLineSDO.getFeatures())? new HashMap<>():(HashMap<String, Object>) forecastOrderLineSDO.getFeatures();
            stringObjectHashMap.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            forecastOrderLineSDO.setFeatures(stringObjectHashMap);
        }
        forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
        return num;
    }

    private void modifyForecastOrderLine(ForecastOrderLineSDO forecastOrderLineSDO,Integer qty) {
        forecastOrderLineSDO.setModifierId(forecastOrderSDO.getModifierId());
        forecastOrderLineSDO.setModifierName(forecastOrderSDO.getModifierName());
        //设置总金额
        if(StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity())&&Objects.nonNull(forecastOrderLineSDO.getUnitPrice())){
            forecastOrderLineSDO.setTotalFee(Long.parseLong(forecastOrderLineSDO.getQuantity())* forecastOrderLineSDO.getUnitPrice());
        }
        ForecastOrderLineSDO orderLineFeatures = getOrderLineFeatures(forecastOrderLineSDO,qty);


        forecastOrderLineWriteRepository.modify(orderLineFeatures);
    }

    /**
     * 预报订单提交   白兴雷
     *
     * @return
     */

    public Result<Boolean> submit(ApiContext apiContext) {
        LoginUser loginUser = epochLoginUserService.getLoginUser();
        //校验仓库是否禁用
        QueryWarehouseByIdRequest byIdRequest = new QueryWarehouseByIdRequest();
        byIdRequest.setId(forecastOrderSDO.getWareHouseCode());
        Result<WarehouseInfo> warehouseInfoResult = unifiedInventoryService.queryWarehouseById(byIdRequest);
        if (warehouseInfoResult == null || warehouseInfoResult.getResult() == null || warehouseInfoResult.getResult().getStatus() == null) {
            return Result.fail("888", "未查询对应的仓库");
        }
        if (warehouseInfoResult.getResult().getStatus() == 2) {
            return Result.fail("999", "此仓库禁用,不允许提交");
        }
        if (CollectionUtils.isEmpty(forecastOrderSDO.getForecastOrderLineSDOList())) {
            throw new FunctionException("OTS-04-001-00-15-001");
        }
        boolean isSucees = true;
        //判断当前状态是否可以提交
        //根据查询结果 判断是时间段还是截止时间 是拦截还是提示
        //如果是拦截的话不允许提交  提示的话可以提交
        MoreConditionQueryRequest moreConditionQueryRequest = new MoreConditionQueryRequest();
        moreConditionQueryRequest.setStrategyType(StrategyTypeEnum.VALIDITY.getCode());
        moreConditionQueryRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());//forecastOrderSDO.getOrganizationCode()
        moreConditionQueryRequest.setChannelCode(forecastOrderSDO.getChannelCode());//forecastOrderSDO.getChannelCode()
        moreConditionQueryRequest.setWareHouseCode(forecastOrderSDO.getWareHouseCode());
        log.info("ForecastOrderEntity|submit|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|request|", JSONObject.toJSONString(moreConditionQueryRequest));
        Result<MoreConditionQueryResponse> moreConditionQueryResponseResult = strategyQueryService.moreConditionQuery(moreConditionQueryRequest);
        log.info("ForecastOrderEntity|submit|"+forecastOrderSDO.getOrderBizId()+"|查询有效期校验|result|", JSONObject.toJSONString(moreConditionQueryResponseResult));
        MoreConditionQueryResponse moreConditionQueryResponse = moreConditionQueryResponseResult.getResult();
        boolean isFlag = false;
        if (Objects.nonNull(moreConditionQueryResponse)) {
            StrategySDO strategySDO = moreConditionQueryResponse.getStrategySDO();
            List<DimensionSDO> dimensionSDOList = strategySDO.getDimensionSDOList();
            DimensionSDO dimensionSDO = dimensionSDOList.get(0);
            //获取规则
            String value = dimensionSDO.getRuleName();
            if (StringUtils.equals(RuleTypeEnum.TIME_POINT.getCode(), value)) {
                //获取规则值
                String ruleValue = dimensionSDO.getRuleValue();
                //判断截止时间是否满足 当前时间大于截止时间 不满足
                boolean compare = CalendarCompareUtil.compareDateTimes(null, ruleValue);
                if (compare) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
//                        throw new FacadeException("OTS-04-001-00-15-018");
                        return Result.fail("OTS-04-001-00-15-018", "预报订单有效性检查失败，不允许提交订单已保存到草稿");
                    } else {
                        isFlag = true;
                    }
                }
            }
            if (StringUtils.equals(RuleTypeEnum.TIME_FRAME.getCode(), value)) {
                String ruleValue = dimensionSDO.getRuleValue();
                String substring = ruleValue.substring(ruleValue.indexOf("[") + 1, ruleValue.indexOf("]") ).replace("\"", "");
                String[] split = substring.split(",");

                String ruleValueSplit = split[0];
                String ruleValueSplit1 = split[1];
                boolean compareDateTimes = CalendarCompareUtil.compareDateTimes(ruleValueSplit, ruleValueSplit1);
                //如果为true满足可以提交
                if (!compareDateTimes) {
                    Boolean executeAction = dimensionSDO.getExecuteAction();
                    if (executeAction) {
                        return Result.fail("OTS-04-001-00-15-018", "预报订单有效性检查失败，不允许提交订单已保存到草稿");
                    } else {
                        isFlag = true;
                    }
                }
            }
        }
        forecastOrderSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
        forecastOrderSDO.setModifierId(apiContext.getEmployeeId());
        forecastOrderSDO.setModifierName(apiContext.getEmployeeName());

        // 提交子单
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            // add by myw,校验子单价格 0303需求 预报单价格校验后移至预报单提交
            ForecastOrderLineSDO query = forecastOrderLineQueryRepository.query(String.valueOf(forecastOrderLineSDO.getId()));

            if (query.getUnitPrice() == null || query.getUnitPrice() < 0L) {
                throw new FunctionException("OTS-04-001-00-15-022");
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getQuantity())) {
                throw new FunctionException("OTS-04-001-00-15-002");
            }
            //生效时，进行每日库存判断
            // 校验每日库存限量 在提交的时候校验每日库存
//            if (ForecastStatusEnum.DRAFT.getNumValue().equals(forecastOrderSDO.getStatus())){
            verifyDailyInv(forecastOrderLineSDO);
//            }
            if (!isFlag) {
                queryAndDeduct(forecastOrderLineSDO);
            }
            forecastOrderLineSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());

            forecastOrderLineWriteRepository.submit(forecastOrderLineSDO);

        }
        if (isFlag) {
            Date vaildBeginTime = this.forecastOrderSDO.getVaildBeginTime();
            Calendar calendar = new GregorianCalendar();
            calendar.setTime(vaildBeginTime);
            //把日期往后增加一天.整数往后推,负数往前移动
            calendar.add(Calendar.DATE, 1);
//                这个时间就是日期往后推一天的结果
            vaildBeginTime = calendar.getTime();
            forecastOrderSDO.setVaildBeginTime(vaildBeginTime);
//            // 设置为未生效 原因和上边注释原因一样
//            forecastOrderSDO.setStatus(ForecastStatusEnum.NOTACTIVE.getNumValue());
        }
        //提交主单
        isSucees = forecastOrderWriteRepository.submit(this.forecastOrderSDO);
        LogUtils.printOperateLog(this.forecastOrderSDO.getId(),ForecastOrderLogEnum.SUBMIT.getForecastOrderLogValue(),"提交预报订单",loginUser);
        //标识效期校验未通过 但是是提示
        if (isFlag) {
            return Result.success(true, "预报订单有效性检查失败，允许提交待调度次日回复");
        }
        return Result.success(isSucees, "预报订单有效性检查通过，耐心等待调度员当日回复");
    }

    private void queryAndDeduct(ForecastOrderLineSDO forecastOrderLineSDO) {
        String isInventory = "A";
        Integer dailyInventory = null;
        String allotLineId = null;
        try {
            QueryAllotAndDeductRequest queryAllotRequest = new QueryAllotAndDeductRequest();
            queryAllotRequest.setOrganizationCode(forecastOrderSDO.getOrganizationCode());
            queryAllotRequest.setChannelCode(forecastOrderSDO.getChannelCode());
            queryAllotRequest.setDepartmentCode(forecastOrderSDO.getDepartmentCode());
            queryAllotRequest.setSalesmanCode(forecastOrderSDO.getSalesmanCode());
            queryAllotRequest.setScItemId(forecastOrderLineSDO.getScItemId());
            Double doubleDuct = Integer.parseInt(forecastOrderLineSDO.getQuantity())/Double.parseDouble(forecastOrderLineSDO.getUnitConvert()== null?"1": forecastOrderLineSDO.getUnitConvert());
            String duct = String.valueOf(new BigDecimal(doubleDuct).setScale(3, RoundingMode.DOWN));
            queryAllotRequest.setDeductQuantity(duct);
            queryAllotRequest.setWarehouseCode(forecastOrderSDO.getWareHouseCode());
            log.info("ForecastOrderEntity|submit|"+forecastOrderSDO.getOrderBizId()+"|获取每日库存请求|request|" + JSON.toJSONString(queryAllotRequest));
            Result<DailyInventoryDeductResponse> result = inventoryAllotLineWriteService.queryAndDeduct(queryAllotRequest);
            log.info("ForecastOrderEntity|submit|"+forecastOrderSDO.getOrderBizId()+"|获取每日库存响应|result|" + JSON.toJSONString(result));
            if (result != null && result.getResult() != null) {
                allotLineId = result.getResult().getAllotLineId();
                dailyInventory = new BigDecimal(result.getResult().getRealDeductQuantity()).multiply(new BigDecimal(forecastOrderLineSDO.getUnitConvert())).intValue();
            }
        }catch (FacadeException ex){
            throw new FunctionException(ex);
        } catch (Exception e) {
            log.error("ForecastOrderEntity|submit|"+forecastOrderSDO.getOrderBizId()+"|获取每日库存异常|exception|", e);

        }

        Map<String, Object> features = forecastOrderLineSDO.getFeatures();
        if (MapUtils.isEmpty(forecastOrderLineSDO.getFeatures())) {
            features = new HashMap<>();
        }
        if (Objects.nonNull(dailyInventory)){
            if (dailyInventory >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
                isInventory = "C";
            } else if (dailyInventory >= 0 && (dailyInventory < Integer.parseInt(forecastOrderLineSDO.getQuantity()))) {
                isInventory = "B";
            }
        }
//                if (dailyInventory >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
//                    isInventory = "C";
//                } else if (dailyInventory > 0 && (dailyInventory < Integer.parseInt(forecastOrderLineSDO.getQuantity()))) {
//                    isInventory = "B";
//                } else {
//                    isInventory = "A";
//                }
        switch (isInventory) {
//                    case "A":
//                        //每日库存为空  表示未分解
////                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_NOT.getNumValue());
//                        features.put(ForecastConstants.DISINTEGRATION_QTY, 0);
//                        break;
            case "B":
                //分解未满足
//                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_INVENTORY_NOT.getNumValue());
                features.put(ForecastConstants.DISINTEGRATION_QTY, dailyInventory);
                features.put(ForecastConstants.DISINTEGRATION_ALLOT_LINE_ID,allotLineId);
                break;
            case "C":
                //分解满足
//                        features.put(ForecastConstants.DISINTEGRATION, DisintegrationInventorySEO.DISINTEGRATION_INVENTORY_YES.getNumValue());
                features.put(ForecastConstants.DISINTEGRATION_QTY, Integer.parseInt(forecastOrderLineSDO.getQuantity()));
                features.put(ForecastConstants.DISINTEGRATION_ALLOT_LINE_ID,allotLineId);
                break;
        }
        forecastOrderLineSDO.setFeatures(features);
    }

    public boolean modifyDetailForecast() {
        LoginUser loginUser = epochLoginUserService.getLoginUser();
        //主订单的修改
        forecastOrderWriteRepository.modifyForecast(this.forecastOrderSDO);
        LogUtils.printOperateLog(this.forecastOrderSDO.getId(),ForecastOrderLogEnum.EDIT.getForecastOrderLogValue(),"编辑预报订单",loginUser);
        //保存新的子订单
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        if (CollectionUtils.isNotEmpty(forecastOrderLineSDOList)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                if (null == forecastOrderLineSDO.getId()) {
                    forecastOrderLineSDO.setStatus(ForecastStatusEnum.WAITING_FOR_REPLY.getNumValue());
                    forecastOrderLineSDO.setMainOrderId(forecastOrderSDO.getId());
                    forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
                }
            }
        }
        return true;
    }

    /*
    更改销售预报单 王成
     */
    public Integer modify() {
        Integer count = 0;
        // 保存预报主单
//        boolean mainFlag= forecastOrderWriteRepository.modify(this.forecastOrderSDO);
//        flag = flag && mainFlag;
        // 保存预报子单
        // 行号
        Integer num = 0;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            forecastOrderLineSDO.setMainOrderId(this.forecastOrderSDO.getId());
            //判断是不是新增的子单 老的子单更新 新的子单创建
//            ForecastOrderLineSDO oldForecastOrderLineSDO = forecastOrderLineQueryRepository.query(forecastOrderLineSDO); //现在通过判断是否传递id来判断   因为根据id查询 如果查询不到会直接报错
            if (StringUtils.isNotBlank(forecastOrderLineSDO.getMainOrderId())) {
                num++;
                forecastOrderLineSDO.setSerialNumber(num.toString());
                Integer modifyCount = forecastOrderLineWriteRepository.modify(forecastOrderLineSDO);
                count += modifyCount;
            } else {
                num++;
                forecastOrderLineSDO.setSerialNumber(num.toString());
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.DRAFT.getNumValue());
                forecastOrderLineSDO.setStatus(ForecastDealStatusSEO.WAITING_DEAL.getStatus());
                forecastOrderLineSDO.setActualTotalReplyAmount(0);
                forecastOrderLineWriteRepository.save(forecastOrderLineSDO);
                count++;
            }
        }
        return count;
    }

    /**
     * 修改预报订单
     */

    public boolean updateReplyQuantity(Integer predictReplyAmount) {
        //修改成功
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            forecastOrderLineSDO.setPredictReplyAmount(predictReplyAmount);
            isSuccess = forecastOrderLineWriteRepository.updateReplyQuantity(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public boolean updateForecastOrderLine() {
        //修改成功
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    /**
     * 确认预报订单 修改预报的处理状态
     */
    public boolean confirmUpdateDealForecast(ApiContext apiContext) {
        //修改订单处理状态为
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        boolean isSucess = true;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ING.getStatus());
            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());
//            Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
            if (ObjectUtils.isEmpty(forecastOrderLineSDO.getPredictReplyAmount())) {
                throw new FunctionException("OTS-04-001-00-15-032","预计回复数量不能为0！");
            }
            if (forecastOrderLineSDO.getPredictReplyAmount() == 0) {
                throw new FunctionException("OTS-04-001-00-15-032","预计回复数量不能为0！");
            }
            isSucess = forecastOrderLineWriteRepository.submit(forecastOrderLineSDO);
        }
        //将数据的信息插入确认队列的表中
        List<DealLineSDO> collect = Nullable.stream(forecastOrderLineSDOList).map(forecastOrderLineSDO -> {
            DealLineSDO dealLineSDO = new DealLineSDO();
            dealLineSDO.setForecastOrderLineId(forecastOrderLineSDO.getId().toString());
            dealLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ING.getStatus());
            dealLineSDO.setDealType(ForecastDealTypeSEO.BATCH_CONFIRM.getDealTypeCode().toString());
            dealLineSDO.setModifierName(forecastOrderLineSDO.getModifierName());
            dealLineSDO.setModifierId(forecastOrderLineSDO.getModifierId());
            dealLineSDO.setDealTime(new Date());
            Date now = new Date();
            SimpleDateFormat f = new SimpleDateFormat("yyyyMMddhhmmss");
            String format = f.format(now);//20211015030520
            dealLineSDO.setBatchNumber(format);
            return dealLineSDO;
        }).collect(Collectors.toList());
        boolean b = dealLineWriteRepository.batchCreate(collect);
        return isSucess;
    }


    /**
     * 确认预报订单 修改预报的处理状态
     */
    public boolean activityUpdateDealForecast(ApiContext apiContext) {
        //TODO 性能优化点： 这里可以直接从内存中获取单据数据，而非重新捞取
        //修改订单处理状态为
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        boolean isSucess = true;
        log.info("查下活动前，预报主单ID={}",this.forecastOrderSDO.getId());
        //补货订单不走活动检查逻辑
        if(!"03".equals(forecastOrderSDO.getOrderType())) {
            List<ActivitySDO> activitySDOS1 = queryActivity(forecastOrderLineSDOList);
            Set<String> haveActivitySubOrderIdSet = new HashSet<>();
            if (CollectionUtils.isNotEmpty(activitySDOS1)) {
                Map<String, List<ActivitySDO>> collect = activitySDOS1.stream().collect(Collectors.groupingBy(ActivitySDO::getSubOrderId));
                if (MapUtils.isNotEmpty(collect)) {
                    for (String subId : collect.keySet()) {
                        ForecastOrderLineSDO forecastOrderLineSDO = forecastOrderLineQueryRepository.query(subId);
                        List<ActivitySDO> activitySDOS = collect.get(subId);
                        //根据活动命中的情况对预报子单进行更新
                        updateActivityInformation(forecastOrderLineSDO, activitySDOS, apiContext);
                    }
                    haveActivitySubOrderIdSet.addAll(collect.keySet());
                }
            }

            forecastOrderLineSDOList.forEach(orderLineSDO -> {
                if (!haveActivitySubOrderIdSet.contains(orderLineSDO.getId().toString())) {
                    DeleteActivityForecastRequest deleteActivityForecastRequest = new DeleteActivityForecastRequest();
                    deleteActivityForecastRequest.setId(String.valueOf(orderLineSDO.getId()));
                    forecastOrderWriteService.deleteActivityForecast(deleteActivityForecastRequest);
                }
            });

        }
        //查询命中活动详情

        return isSucess;
    }


    private boolean updateActivityInformation(ForecastOrderLineSDO forecastOrderLineSDO,List<ActivitySDO> activitySDOS,ApiContext apiContext){
        Map<String, Object> features = forecastOrderLineSDO.getFeatures();
        if (CollectionUtils.isEmpty(activitySDOS) && MapUtils.isNotEmpty(features)) {
            log.info("活动未命中::" + forecastOrderLineSDO.getIdemId());
            if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                features.remove(ForecastConstants.ACTIVITY_DETAILS);
            }
            return true;
        }

        //修改状态为检查中
//            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CHECk_ING.getStatus());
        if (apiContext != null) {
            forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
            forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());
        }
        //调用活动检查接口 获取返回值判断命中活动情况 list<object>
        /**
         *  ZS01-买赠
         *              * ZS02-搭赠
         *              * ZS03-特价
         *              * ZS42-补货
         */
        if (CollectionUtils.isNotEmpty(activitySDOS)) {
            //设置查询活动参数
            features.remove(ForecastConstants.ACTIVITY_DETAILS);
            features.put(ForecastConstants.ACTIVITY_MESSAGE, "活动检查成功！");
            activitySDOS.forEach(i->{
                i.setIsSelect(false);
            });

            //按活动号进行排序，当前是升序排列
            Collections.sort(activitySDOS, Comparator.comparing(ActivitySDO::getActivityCode));

            features.put(ForecastConstants.ACTIVITY_DETAILS,activitySDOS);
            if (activitySDOS.size() > 1) {
                //大于一的时候命中多个活动 表示后续需要修改
                features.put(ForecastConstants.ACTIVITY_TAG, 1);
                //对多个活动要进行设置选中逻辑。
                // 同种活动类型设置第一个选中，不同种活动类型设置，对第一个活动类型设置为选中，其他的均为不选中
                Map<String, List<ActivitySDO>> map = activitySDOS.stream().collect(Collectors.groupingBy(ActivitySDO::getActivityType));
                for (Map.Entry<String, List<ActivitySDO>> entry : map.entrySet()) {
                    List<ActivitySDO> value = entry.getValue();
                    for (int i = 0; i < value.size(); i++) {
                        if (i == 0) {
                            value.get(0).setIsSelect(true);
                        } else {
                            value.get(i).setIsSelect(false);
                        }
                    }
                }

            } else if (1 == activitySDOS.size()) {
                // 并且只有一个商品 将活动信息存放到features中
                if ("ZS42".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    features.put(ForecastConstants.ACTIVITY_TAG, 0);
                    activitySDOS.get(0).setIsSelect(true);
                    features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                    features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                }
                // 赠品活动
                if ("ZS02".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    if (activitySDOS.get(0).getGiftList().size() > 1) {
                        features.put(ForecastConstants.ACTIVITY_TAG, 1);
                    } else {
                        features.put(ForecastConstants.ACTIVITY_TAG, 0);
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                        activitySDOS.get(0).setIsSelect(true);
                        features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                    }
                }
                if ("ZS03".equals(activitySDOS.get(0).getActivityType()) && activitySDOS.size() == 1) {
                    if (activitySDOS.get(0).getActivitydeal() < forecastOrderLineSDO.getPredictReplyAmount()) {
                        features.put(ForecastConstants.ACTIVITY_TAG, 1);
                    } else {
                        features.put(ForecastConstants.ACTIVITY_TAG, 0);
                        features.put(ForecastConstants.ACTIVITY_NUMBER, activitySDOS.get(0).getActivityTermid());
                        activitySDOS.get(0).setIsSelect(true);
                        features.put(ForecastConstants.ACTIVITY_DETAILS, activitySDOS);
                        //只有特价活动有特价 活动特价
                        forecastOrderLineSDO.setActivityPrice(activitySDOS.get(0).getSpecialOfferPrice());
                        //设置活动总金额
                        if (null != activitySDOS.get(0).getSpecialOfferPrice()
                                && StringUtils.isNotEmpty(forecastOrderLineSDO.getQuantity())) {
                            forecastOrderLineSDO.setTotalActivityFee(activitySDOS.get(0).getSpecialOfferPrice()
                                    * Long.parseLong(forecastOrderLineSDO.getQuantity()));
                        }
                    }
                }
            }
            //标识命中活动
            features.put(ForecastConstants.ISSELECT_ACTIVITY, 1);
            features.put(ForecastConstants.ACTIVITY_TYPE, activitySDOS.get(0).getActivityType());
            forecastOrderLineSDO.setFeatures(features);
            forecastOrderLineSDO.setActivityName(activitySDOS.get(0).getActivityName());
            //活动id
            forecastOrderLineSDO.setActivityCode(activitySDOS.get(0).getActivityCode());
            //设置活动号
            forecastOrderLineSDO.setActivityNumber(activitySDOS.get(0).getActivityTermid());
        } else {
            //标识未命中活动
            features.put(ForecastConstants.ISSELECT_ACTIVITY, 0);
            features.put(ForecastConstants.ACTIVITY_MESSAGE, "该单据未命中活动！");
        }
        return forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
    }

    private List<ActivitySDO> queryActivity(List<ForecastOrderLineSDO> forecastOrderLineSDOs) {
        QueryActivityRequest request = new QueryActivityRequest();
        List<ActivityInfoRequest> activityInfoRequestList = new ArrayList<>();
        //构建活动信息请求列表
        buildActivityInfoRequestList(forecastOrderLineSDOs, activityInfoRequestList);
        request.setActivityInfoRequestList(activityInfoRequestList);
        Map<String, String> map = new HashMap<>();
        map.put(CODE_FLAG, INNER_CODE_TO_OUT_CODE);
        request.setFeatures(map);
        //获取出参
        List<ActivitySDO> activitySDOS = new ArrayList<>();
        try {
            Result<ActivityResponse> activityResponseResult = activityQueryService.batchQueryCanUsingActivityExpand(request);
            ActivityResponse result = activityResponseResult.getResult();
            if (Objects.nonNull(result) && CollectionUtils.isNotEmpty(result.getActivityInfoResponseList())) {
                for(ActivityInfoResponse activityInfoResponse:result.getActivityInfoResponseList()){
                    List<ActivityTermResponse> activityTermList = activityInfoResponse.getActivityTermList();
                    ActivitySDO activitySDO = new ActivitySDO();
                    activitySDO.setIsSelect(false);
                    //设置活动id
                    activitySDO.setActivityCode(activityInfoResponse.getActivityId());

                    //设置子单id
                    activitySDO.setSubOrderId(activityInfoResponse.getSubOrderId());
                    //设置活动名称
                    activitySDO.setActivityName(activityInfoResponse.getActivityNoteName());
                    //设置活动剩余量
                    activitySDO.setActivitydeal(activityTermList.get(0).getActivityRemainingQuantity());
                    //设置版本号
                    activitySDO.setVersion(activityTermList.get(0).getVersion());
                    /**
                     * ZS01-买赠
                     * ZS02-搭赠
                     * ZS03-特价
                     * ZS42-补货
                     */
                    activitySDO.setActivityType(activityInfoResponse.getActivityFacadeCode());
                    //设置活动力度说明
                    activitySDO.setIntensityOfActivityDesc(activityTermList.get(0).getIntensityOfActivityDesc());
                    //设置活动剩余金额
                    activitySDO.setActivityfee(activityTermList.get(0).getActivityRemainingFee());
                    //设置项目id
                    activitySDO.setActivityTermid(activityTermList.get(0).getActivityTermId());
                    //增品活动的活动类型
                    activitySDO.setGiftActivityType(activityTermList.get(0).getGiftActivityType());
                    //设置特价
                    if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(activityInfoResponse.getActivityFacadeCode())) {
                        BigDecimal specialPrice = new BigDecimal(activityTermList.get(0).getSpecialOfferPrice());
                        //特价要从元转换成分
                        activitySDO.setSpecialOfferPrice(specialPrice.longValue());
                        //设置公用组，只有特价有
                        activitySDO.setCommonGroupFlag(activityTermList.get(0).getCommonGroupFlag());
                    }
                    List<GiftSDO> chooseGiftList = new ArrayList<>();
                    if (ActivityTypeEnum.TAKE_GIFT.getValue().equals(activityInfoResponse.getActivityFacadeCode())) {
                        List<ActivityItemInfo> giftList1 = activityTermList.get(0).getGiftList();
                        if (CollectionUtils.isNotEmpty(giftList1)) {
                            for (ActivityItemInfo activityItemInfo : giftList1) {
                                GiftSDO giftSDO = new GiftSDO();
                                giftSDO.setGiftName(activityItemInfo.getItemName());
                                giftSDO.setGiftNumber(activityItemInfo.getItemQuantity());
                                giftSDO.setScItemId(activityItemInfo.getItemId());
                                giftSDO.setGiftSalesUnitCode(activityItemInfo.getSalesUnit());
                                giftSDO.setGiftUnitCode(activityItemInfo.getStockUnit());
                                giftSDO.setConversionUnit(activityItemInfo.getConversionUnit());
                                try {
                                    ScItemUnitLoadListRequest scItemUnitLoadListRequest = new ScItemUnitLoadListRequest();
                                    scItemUnitLoadListRequest.setCode(activityItemInfo.getSalesUnit());
                                    Result<List<ScItemUnit>> listResult = scItemUnitService.loadScItemUnitList(scItemUnitLoadListRequest);
                                    if (Objects.nonNull(listResult) && CollectionUtils.isNotEmpty(listResult.getResult())) {
                                        ScItemUnit scItemUnit = listResult.getResult().get(0);
                                        giftSDO.setGiftSalesUnit(scItemUnit.getName());
                                    }
                                    IdQueryRequest idQueryRequest = new IdQueryRequest();
                                    idQueryRequest.setId(giftSDO.getScItemId());
                                    Result<ScItemSDO> scItemById = scItemQueryService.getScItemById(idQueryRequest);
                                    ScItemSDO scItemSDO = scItemById.getResult();
                                    if (Objects.nonNull(scItemSDO)) {
                                        giftSDO.setScItemCode(scItemSDO.getOuterId());
                                    }
                                } catch (Exception e) {
                                    log.error("查询商品属性失败", e);
                                }
                                Long price = -1L;
                                price = priceQueryUtils.obtainGiftPrice(forecastOrderSDO, giftSDO);
                                if (price < 0) {
                                    log.error("查询赠品活动价格失败,赠品Id:" + activityItemInfo.getItemId());
                                    throw new FacadeException("OTS-04-001-00-15-033");
                                }
                                giftSDO.setGiftPrice(price);
                                chooseGiftList.add(giftSDO);
                            }
                        }
                    }
                    activitySDO.setGiftList(chooseGiftList);
                    activitySDO.setChooseGiftList(chooseGiftList);
                    activitySDOS.add(activitySDO);
                }
            }
        } catch (Exception e) {
            log.error("查询活动异常处理:", e);
        }
        return activitySDOS;
    }
    /**
     * 补货活动查询信息参数构建
     */
    private ActivityInfoRequest createActivityInfoRequest(ForecastOrderLineSDO forecastOrderLineSDO){
        ActivityInfoRequest infoRequest = new ActivityInfoRequest();
        infoRequest.setClientId(forecastOrderSDO.getCustomerCode());
        infoRequest.setMainOrderId(this.forecastOrderSDO.getId());
        infoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
        infoRequest.setActivityUseTime(new Date());
        infoRequest.setDeliveryDate(this.forecastOrderSDO.getCustomerExpectTDate());
        infoRequest.setSalesOrganization(forecastOrderSDO.getOrganizationCode());
        infoRequest.setBusinessChannel(forecastOrderSDO.getChannelCode());
        infoRequest.setShipAddressId(forecastOrderSDO.getReceiveAddressCode());
        infoRequest.setOrderType(forecastOrderSDO.getOrderType());
        List<ActivityItemInfoRequest> itemList = new ArrayList<>();
        ActivityItemInfoRequest itemInfoRequest = new ActivityItemInfoRequest();
        itemInfoRequest.setItemId(forecastOrderLineSDO.getScItemId());
        itemInfoRequest.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
        itemInfoRequest.setItemQuantity(Long.parseLong(String.valueOf(forecastOrderLineSDO.getPredictReplyAmount())));
        itemList.add(itemInfoRequest);
        infoRequest.setItemList(itemList);
        return infoRequest;
    }

    /**
     * 构建活动信息请求列表
     * @param forecastOrderLineSDOs
     * @param activityInfoRequestList
     */
    private void buildActivityInfoRequestList(List<ForecastOrderLineSDO> forecastOrderLineSDOs, List<ActivityInfoRequest> activityInfoRequestList) {
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOs) {

            ActivityInfoRequest infoRequest = new ActivityInfoRequest();
            List<ActivityItemInfoRequest> itemList = new ArrayList<>();
            ActivityItemInfoRequest itemInfoRequest = new ActivityItemInfoRequest();
            try {
                infoRequest.setClientId(forecastOrderSDO.getCustomerCode());
                infoRequest.setMainOrderId(this.forecastOrderSDO.getId());
                infoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
                infoRequest.setActivityUseTime(new Date());
                infoRequest.setDeliveryDate(this.forecastOrderSDO.getCustomerExpectTDate());
                infoRequest.setSalesOrganization(forecastOrderSDO.getOrganizationCode());
                infoRequest.setBusinessChannel(forecastOrderSDO.getChannelCode());
                infoRequest.setOrderType(forecastOrderSDO.getOrderType());
                infoRequest.setShipAddressId(forecastOrderSDO.getReceiveAddressCode());
                itemInfoRequest.setItemId(forecastOrderLineSDO.getScItemId());
                itemInfoRequest.setSalesUnit(forecastOrderLineSDO.getSaleUnitCode());
                itemInfoRequest.setItemQuantity(Long.parseLong(String.valueOf(forecastOrderLineSDO.getPredictReplyAmount())));
                itemList.add(itemInfoRequest);
                infoRequest.setItemList(itemList);

                Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
                features.put(ForecastConstants.ACTIVITY_CHECK_PARAMS, infoRequest);
                forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
            }catch (Exception e){
                log.error("ERROR:Build activity info request failed", e);
            }

            activityInfoRequestList.add(infoRequest);
        }
    }

    /**
     * 确认预报订单 预报订单确认检查
     */
    @Deprecated
    public List<ConfirmForecastResponse> confirmCheckForecast(ConfirmForecastRequest confirmForecastRequest) {
        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse success = new ConfirmForecastResponse();
        //成功
        success.setTag("1");
        ConfirmForecastResponse failedForecastResponse = new ConfirmForecastResponse();
        //失败
        failedForecastResponse.setTag("2");
        ConfirmForecastResponse isCredit = new ConfirmForecastResponse();
        //信贷失败
        isCredit.setTag("3");
        List<String> successIds = new ArrayList<>();
        List<String> failedIds = new ArrayList<>();
        List<String> creditIds = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        //添加库存校验
        List<ConfirmForecastResponse> confirmForecastResponsesList = inventoryCheck(forecastOrderLineSDOList);
        if (CollectionUtils.isEmpty(confirmForecastResponsesList)) {
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                //判断子订单是否需要经过活动检查
                backForecastUpdate(forecastOrderLineSDO, "库存不足不可以生成销售订单！");

            }
            return confirmForecastResponsesList;
        }
        Boolean[]  isNeedCallParticipateActivity = new Boolean[1];
        isNeedCallParticipateActivity[0] = true;
        //start
        String sequenceNo = confirmForecastRequest.getSequenceNo();
        ParticipateInActivityResponse participateInActivityResponse1 = occupyActivity(forecastOrderLineSDOList, isNeedCallParticipateActivity,sequenceNo);
        if(isNeedCallParticipateActivity[0]){
            if (Objects.nonNull(participateInActivityResponse1)
                    && CollectionUtils.isNotEmpty(participateInActivityResponse1.getParticipateActivityResponseList())) {

                List<ParticipateActivityInfoResponse> participateActivityResponseList = participateInActivityResponse1.getParticipateActivityResponseList();
                Map<String, List<ParticipateActivityInfoResponse>> participateActivityInfoResponseMap = participateActivityResponseList.stream()
                        .collect(Collectors.groupingBy(e -> e.getSubOrderId()));

                for (String subId : participateActivityInfoResponseMap.keySet()) {
                    ForecastOrderLineSDO forecastOrderLineSDO1 = forecastOrderLineQueryRepository.query(subId);
                    Map<String, Object> features = forecastOrderLineSDO1.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO1.getFeatures();
                    List<ParticipateActivityInfoResponse> participateActivityInfoResponses = participateActivityInfoResponseMap.get(subId);
                    //活动返回值集合中有为false 的则为失败
                    List<ParticipateActivityInfoResponse> panduan = participateActivityInfoResponses.stream().filter(i ->
                            false == i.getParticipateResult()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(panduan)) {
                        failedIds.add(subId);
                        //更新子单的失败信息
                        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                            //判断子订单是否需要经过活动检查
                            backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");

                        }
                        List<ConfirmForecastResponse> confirmForecastResponseYuan=new ArrayList<>();
                        return confirmForecastResponseYuan;
                    }

                    //补全 feature 中的字段，原因一个字段对应多个不同类型的活动，需要添加不同的字段信息
                    for (ParticipateActivityInfoResponse participateActivityInfoResponse : participateActivityInfoResponses) {
                        if (participateActivityInfoResponse.getParticipateResult()) {
                            if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(participateActivityInfoResponse.getActivityType())) {
                                //特价活动添加占用活动成功的原品数量
                                features.put(ForecastConstants.ACTIVITY_INVENTORY, participateActivityInfoResponse.getParticipateSuccessItemCount());
                            }
//                        该字段会被覆盖，属于正常情况
                            features.put(ForecastConstants.CONFIRM_MESSAGE, participateActivityInfoResponse.getParticipateResultMsg());
                        }
                    }
                    //活动检查通过  获取活动量
                    forecastOrderLineSDO1.setFeatures(features);
                    forecastOrderLineWriteRepository.update(forecastOrderLineSDO1);

                    // todo bxl 袁登，为什么要这样做，不太懂
                    updateDealQueueStatus(forecastOrderLineSDO1);
                    successIds.add(subId);
                }
            }else{
                //异常情况活动占用失败！更新子单的失败信息
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    //判断子订单是否需要经过活动检查
                    if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
                        backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
                    }
                }
            }
        }

        //库存校验成功的，没有活动的子单
        forecastOrderLineSDOList.stream().forEach(forecastOrderLineSDO -> {
            Map<String,Object> features = forecastOrderLineSDO.getFeatures();
            if(StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())&&MapUtils.isNotEmpty(features)&&Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))){
                List<ActivitySDO> activitySDOList = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                List<ActivitySDO> activitySDOS = activitySDOList.stream().filter(activitySDO -> activitySDO.getIsSelect() == true).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(activitySDOS)){
                    successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                }
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())) {
                successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
            }
        });

        failedForecastResponse.setIds(failedIds);
        success.setIds(successIds);
        isCredit.setIds(creditIds);
        confirmForecastResponses.add(isCredit);
        confirmForecastResponses.add(success);
        confirmForecastResponses.add(failedForecastResponse);
        return confirmForecastResponses;
    }

    /**
     * 确认预报订单 预报订单确认检查
     */
    public ConfirmForecastResponse confirmCheckForecastNew(ConfirmForecastRequest confirmForecastRequest) {
        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse confirmForecastResponse = new ConfirmForecastResponse();
//        ConfirmForecastResponse success = new ConfirmForecastResponse();
        //成功
//        success.setTag("1");
//        ConfirmForecastResponse failedForecastResponse = new ConfirmForecastResponse();
//        //失败
//        failedForecastResponse.setTag("2");
//        ConfirmForecastResponse isCredit = new ConfirmForecastResponse();
//        //信贷失败
//        isCredit.setTag("3");
        List<String> successIds = new ArrayList<>();
        List<String> failedIds = new ArrayList<>();
        Map<String, String> successIdsMap = new HashMap<>();
        Map<String, String> failedIdsMap = new HashMap<>();
//        List<String> creditIds = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        //添加库存校验
        ConfirmForecastResponse inventoryCheckResp = inventoryCheckNew(forecastOrderLineSDOList);
        if (MapUtils.isNotEmpty(inventoryCheckResp.getFailOrderLineMap())) {
//            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
//                failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
//                //判断子订单是否需要经过活动检查
//                backForecastUpdate(forecastOrderLineSDO, "库存不足不可以生成销售订单！");
//
//            }
            log.info("批量确认-库存校验失败"+JSON.toJSONString(inventoryCheckResp));
            return inventoryCheckResp;
        }
        Boolean[]  isNeedCallParticipateActivity = new Boolean[1];
        isNeedCallParticipateActivity[0] = true;
        //start
        String sequenceNo = confirmForecastRequest.getSequenceNo();
        //子单 id 与子单的映射
        Map<String, ForecastOrderLineSDO> subOrderIdMap = forecastOrderLineSDOList.stream().collect(Collectors.toMap(subOrder -> subOrder.getId().toString(), Function.identity()));
        //占用活动
        ParticipateInActivityResponse inActivityResponse = occupyActivity(forecastOrderLineSDOList, isNeedCallParticipateActivity,sequenceNo);
        if(isNeedCallParticipateActivity[0]){
            if (Objects.nonNull(inActivityResponse)
                    && CollectionUtils.isNotEmpty(inActivityResponse.getParticipateActivityResponseList())) {

                List<ParticipateActivityInfoResponse> participateActivityResponseList = inActivityResponse.getParticipateActivityResponseList();
                Map<String, List<ParticipateActivityInfoResponse>> participateActivityInfoResponseMap = participateActivityResponseList.stream()
                        .collect(Collectors.groupingBy(e -> e.getSubOrderId()));

                for (String subId : participateActivityInfoResponseMap.keySet()) {
                    ForecastOrderLineSDO forecastOrderLine =  subOrderIdMap.get(subId);
                    Map<String, Object> features = forecastOrderLine.getFeatures() == null ? new HashMap<>() : forecastOrderLine.getFeatures();
                    List<ParticipateActivityInfoResponse> participateActivityInfoResponses = participateActivityInfoResponseMap.get(subId);
                    //活动返回值集合中有为false 的则为失败
                    List<ParticipateActivityInfoResponse> panduan = participateActivityInfoResponses.stream().filter(i ->
                            false == i.getParticipateResult()).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(panduan)) {
                        Map<String, String> activityFailed = panduan.stream().collect(Collectors.toMap(ParticipateActivityInfoResponse::getSubOrderId,ParticipateActivityInfoResponse::getParticipateResultMsg));

                        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
                        Map<String, String> fail = new HashMap<>();
                        fail.put(subId,activityFailed.get(subId));
                        forecastResponse.setMessage(activityFailed.get(subId));
                        forecastResponse.setFailOrderLineMap(fail);
                        //更新子单的失败信息,是否可以先暂时不更新 todo 黔雷
//                        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
//                            //判断子订单是否需要经过活动检查
//                                backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                        }
//                        List<ConfirmForecastResponse> confirmForecastResponseYuan=new ArrayList<>();
                        log.info("批量确认-活动校验失败"+JSON.toJSONString(forecastResponse));
                        return forecastResponse;
                    }

                    //补全 feature 中的字段，原因一个字段对应多个不同类型的活动，需要添加不同的字段信息
                    for (ParticipateActivityInfoResponse participateActivityInfoResponse : participateActivityInfoResponses) {
                        if (participateActivityInfoResponse.getParticipateResult()) {
                            if (ActivityTypeEnum.SPECIAL_OFFER_PRICE.getValue().equals(participateActivityInfoResponse.getActivityType())) {
                                //特价活动添加占用活动成功的原品数量
                                features.put(ForecastConstants.ACTIVITY_INVENTORY, participateActivityInfoResponse.getParticipateSuccessItemCount());

                            }
//                        该字段会被覆盖，属于正常情况
                            features.put(ForecastConstants.CONFIRM_MESSAGE, participateActivityInfoResponse.getParticipateResultMsg());
                            successIdsMap.put(subId,participateActivityInfoResponse.getParticipateResultMsg());
                        }
                    }
                    //活动检查通过  获取活动量
                    forecastOrderLine.setFeatures(features);
                    forecastOrderLineWriteRepository.update(forecastOrderLine);

                    updateDealQueueStatus(forecastOrderLine);
                    successIds.add(subId);
                    if (!successIdsMap.containsKey(subId)){
                        successIdsMap.put(subId,"确认成功");
                    }
                }
            }else{
                //异常情况活动占用失败！更新子单的失败信息
                for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
                    failedIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    confirmForecastResponse.setMessage(ACTIVITY_OCCUPY_EXCEPTION);
                    failedIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()),ACTIVITY_OCCUPY_EXCEPTION);
                    confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
                    //判断子订单是否需要经过活动检查, todo qjg 如果把这个注释掉，失败的预报子单也就无法推进到终态了
//                    if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
//                        backForecastUpdate(forecastOrderLineSDO, "异常情况活动占用失败！");
//                    }
                }
                return confirmForecastResponse;
            }
        }

        //库存校验成功的，没有活动的子单
        forecastOrderLineSDOList.stream().forEach(forecastOrderLineSDO -> {
            Map<String,Object> features = forecastOrderLineSDO.getFeatures();
            if(StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())&&MapUtils.isNotEmpty(features)&&Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))){
                List<ActivitySDO> activitySDOList = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                List<ActivitySDO> activitySDOS = activitySDOList.stream().filter(activitySDO -> activitySDO.getIsSelect() == true).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(activitySDOS)){
                    successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                    successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()),"确认成功");
                }
            }

            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())) {
                successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
                successIdsMap.put(String.valueOf(forecastOrderLineSDO.getId()),"确认成功");
            }
        });

//        failedForecastResponse.setIds(failedIds);
//        success.setIds(successIds);
//        isCredit.setIds(creditIds);
//        confirmForecastResponses.add(isCredit);
//        confirmForecastResponses.add(success);
//        confirmForecastResponses.add(failedForecastResponse);
        confirmForecastResponse.setFailOrderLineMap(failedIdsMap);
        confirmForecastResponse.setSuccessOrderLineMap(successIdsMap);
        return confirmForecastResponse;
    }

    /**
     * 更新处理队列中的活动状态 ，当前方法更新为"确认完成"状态
     * @param forecastOrderLineSDO1
     */
    private void updateDealQueueStatus(ForecastOrderLineSDO forecastOrderLineSDO1) {
        DealLineSDO dealLineSDO = new DealLineSDO();
        dealLineSDO.setForecastOrderLineId(String.valueOf(forecastOrderLineSDO1.getId()));
        dealLineSDO.setDealType("2");
        Result<List<DealLineQueue>> listResult = dealLineQueryRepository.queryProgressQueueResult(dealLineSDO);

        //更新处理队列中的状态
        List<DealLineQueue> collect = Nullable.stream(listResult.getResult()).map(it -> {
            it.setDealTime(new Date());
            it.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
            return it;
        }).collect(Collectors.toList());
//        TODO 袁登优化
        for (DealLineQueue dealLineQueue : collect) {
            boolean b = dealLineWriteRepository.update(dealLineQueue);
        }
    }
    @Deprecated
    private List<ConfirmForecastResponse> inventoryCheck(List<ForecastOrderLineSDO> forecastOrderLineSDOList) {
        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse success = new ConfirmForecastResponse();
        //成功
        success.setTag("1");
        ConfirmForecastResponse failed = new ConfirmForecastResponse();
        //失败
        failed.setTag("2");
        List<String> successIds = new ArrayList<>();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            QueryAvailableInventoryRequest queryAvailableInventoryRequest = new QueryAvailableInventoryRequest();
            queryAvailableInventoryRequest.setType("1");
            queryAvailableInventoryRequest.setWarehouseAreaId(forecastOrderSDO.getWareHouseCode());
            queryAvailableInventoryRequest.setGoodsId(forecastOrderLineSDO.getScItemId());
            log.info("查询仓库库存入参：{}", JSONObject.toJSONString(queryAvailableInventoryRequest));
            BigDecimal inventory = BigDecimal.valueOf(forecastOrderQueryRepository.queryInventory(queryAvailableInventoryRequest)).setScale(3,RoundingMode.DOWN);
////            Integer inventory=10000;
//            Map<String, Object> features=forecastOrderLineSDO.getFeatures()==null?new HashMap<>():forecastOrderLineSDO.getFeatures();
            BigDecimal predictReplyAmount = forecastOrderLineSDO.getPredictReplyAmount() == null ? BigDecimal.ZERO : new BigDecimal(forecastOrderLineSDO.getPredictReplyAmount()).divide(new BigDecimal(forecastOrderLineSDO.getUnitConvert()),3,RoundingMode.DOWN).setScale(3,RoundingMode.DOWN);
            if (predictReplyAmount.compareTo(inventory)>0 ) {
                List<ConfirmForecastResponse> confirmForecastResponses1 = new ArrayList<>();
                backForecastUpdate(forecastOrderLineSDO, "库存不足不可以生成销售订单！");
                //主要是为了返回空对象列表
                return confirmForecastResponses1;
            }
            successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
        }
        success.setIds(successIds);
        confirmForecastResponses.add(success);
        return confirmForecastResponses;
    }
    private ConfirmForecastResponse inventoryCheckNew(List<ForecastOrderLineSDO> forecastOrderLineSDOList) {
//        List<ConfirmForecastResponse> confirmForecastResponses = new ArrayList<>();
        ConfirmForecastResponse forecastResponse = new ConfirmForecastResponse();
        //成功
//        forecastResponse.setTag("1");
        Map<String, String> success = new HashMap<>();
        Map<String, String> fail = new HashMap<>();
//        ConfirmForecastResponse failed = new ConfirmForecastResponse();
        //失败
//        failed.setTag("2");
//        List<String> successIds = new ArrayList<>();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            QueryAvailableInventoryRequest queryAvailableInventoryRequest = new QueryAvailableInventoryRequest();
            queryAvailableInventoryRequest.setType("1");
            queryAvailableInventoryRequest.setWarehouseAreaId(forecastOrderSDO.getWareHouseCode());
            queryAvailableInventoryRequest.setGoodsId(forecastOrderLineSDO.getScItemId());
            log.info("查询仓库库存入参：{}", JSONObject.toJSONString(queryAvailableInventoryRequest));
            BigDecimal inventory = BigDecimal.valueOf(forecastOrderQueryRepository.queryInventory(queryAvailableInventoryRequest)).setScale(3,RoundingMode.UP);
////            Integer inventory=10000;
//            Map<String, Object> features=forecastOrderLineSDO.getFeatures()==null?new HashMap<>():forecastOrderLineSDO.getFeatures();
            BigDecimal predictReplyAmount = forecastOrderLineSDO.getPredictReplyAmount() == null ? BigDecimal.ZERO : new BigDecimal(forecastOrderLineSDO.getPredictReplyAmount()).divide(new BigDecimal(forecastOrderLineSDO.getUnitConvert()),3,RoundingMode.UP).setScale(3,RoundingMode.UP);
            if (predictReplyAmount.compareTo(inventory)>0 ) {
//                List<ConfirmForecastResponse> confirmForecastResponses1 = new ArrayList<>();
                fail.put(String.valueOf(forecastOrderLineSDO.getId()),INVENTORY_CHECK_FAIL);
                forecastResponse.setMessage(INVENTORY_CHECK_FAIL);
//                backForecastUpdate(forecastOrderLineSDO, INVENTORY_CHECK_FAIL);
                //主要是为了返回空对象列表
                forecastResponse.setFailOrderLineMap(fail);
                return forecastResponse;
            }
//            successIds.add(String.valueOf(forecastOrderLineSDO.getId()));
            success.put(String.valueOf(forecastOrderLineSDO.getId()),"成功");

        }
//        forecastResponse.setIds(successIds);
        forecastResponse.setFailOrderLineMap(fail);
        forecastResponse.setSuccessOrderLineMap(success);
//        confirmForecastResponses.add(forecastResponse);
        return forecastResponse;
    }

    /**
     * 确认校验失败，更新子弹处理状态
     *
     * @param forecastOrderLineSDO 子单
     * @param message              失败信息
     */
    public void backForecastUpdate(ForecastOrderLineSDO forecastOrderLineSDO, String message) {
        Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ?
                new HashMap<>() : forecastOrderLineSDO.getFeatures();
        features.put(ForecastConstants.CONFIRM_MESSAGE, message);
        forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
        forecastOrderLineSDO.setFeatures(features);
        forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
//           todo 袁登
        updateDealQueueStatus(forecastOrderLineSDO);
    }

    /**
     * 该方法名字出校验活动，本质是参加活动（是扣减活动的剩余金额和活动剩余数量）
     *
     * @param forecastOrderLineSDOList 子单列表
     * @param isNeedCallParticipateActivity
     * @return 参加活动的结果
     */
    private ParticipateInActivityResponse occupyActivity(List<ForecastOrderLineSDO> forecastOrderLineSDOList, Boolean[] isNeedCallParticipateActivity,String sequenceNo) {
        ParticipateActivityRequest participateActivityRequest = new ParticipateActivityRequest();
        List<ParticipateActivityInfoRequest> participateActivityInfoList = new ArrayList<>();
        //设置查询活动时的参数
        QueryActivityRequest queryActivityRequest = new QueryActivityRequest();
        List<ActivityInfoRequest> activityInfoRequestList = new ArrayList<>();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            Map<String, Object> features = forecastOrderLineSDO.getFeatures() == null ? new HashMap<>() : forecastOrderLineSDO.getFeatures();
            //判断子订单是否需要经过活动检查
            if (StringUtils.isNotEmpty(forecastOrderLineSDO.getActivityCode())) {
                //添加活动参数
                List<ActivitySDO> activitySDOS = new ArrayList<>();
                if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                    activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
                }

                //补货活动单独处理
                if (SaleOrderTag.REPLENISH_FORECAST.getCode().equals(this.forecastOrderSDO.getOrderType())) {
                    ActivitySDO activitySDO = new ActivitySDO();
                    Map<String, Object> features1 = forecastOrderLineSDO.getFeatures();
                    //feature 不为空，活动编码不为空，添加到活动列表中
                    if (MapUtils.isNotEmpty(features1)) {
                        Integer version = features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION) == null ? 0 :
                                Integer.parseInt(String.valueOf(features1.get(ForecastConstants.REPLENISHMENT_ACTIVITY_VERSION)));

                        String activityTermId = features1.get(ForecastConstants.ACTIVITY_NUMBER) == null ? "" :
                                String.valueOf(features1.get(ForecastConstants.ACTIVITY_NUMBER));
                        String activityCode = forecastOrderLineSDO.getActivityCode();
                        //更新成最新的活动版本
                        version = updateNewVersion(activitySDOS, activityCode, activityTermId, version);

                        //如果版本号或者活动的termId为空，直接遍历下一个子单
                        if (Objects.isNull(version) || version == 0 || StringUtils.isBlank(activityTermId)) {
                            continue;
                        }
                        activitySDO.setVersion(version);
                        activitySDO.setActivityTermid(activityTermId);
                        activitySDO.setActivityCode(activityCode);
                        activitySDO.setIsSelect(true);
                        activitySDOS.add(activitySDO);
                    }
                }

                for (ActivitySDO activitySDO : activitySDOS) {
                    if (Objects.isNull(activitySDO)
                            || Objects.isNull(activitySDO.getIsSelect())
                            || !activitySDO.getIsSelect()) {
                        continue;
                    }
                    //加入子单的查询活动入参
                    if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS))) {
                        ActivityInfoRequest activityInfoRequest = JSONObject.parseObject(JSONObject.toJSONString(features.get(ForecastConstants.ACTIVITY_CHECK_PARAMS)), ActivityInfoRequest.class);
                        activityInfoRequestList.add(activityInfoRequest);
                    }else{
                        ActivityInfoRequest activityInfoRequest = createActivityInfoRequest(forecastOrderLineSDO);
                        activityInfoRequestList.add(activityInfoRequest);
                    }

                    //参加活动的入参
                    ParticipateActivityInfoRequest participateActivityInfoRequest = buildParticipateActivityInfoRequest(forecastOrderLineSDO, activitySDO,sequenceNo);
                    participateActivityInfoList.add(participateActivityInfoRequest);
                }
            }
        }

        Map<String, String> map = new HashMap<>();
        //移除重复的查询活动请求数据
        activityInfoRequestList = removeRepeatActivityInfoRequest(activityInfoRequestList);

        //查询活动请求封装
        queryActivityRequest.setActivityInfoRequestList(activityInfoRequestList);
        Map<String, String> features = new HashMap<>();
        features.put(CODE_FLAG, INNER_CODE_TO_OUT_CODE);
        queryActivityRequest.setFeatures(features);
        //添加活动查询参数
        map.put(ADD_ACTIVITY_QUERY_PARAM, JSONObject.toJSONString(queryActivityRequest));

        //内外码转换
        map.put(CODE_FLAG, INNER_CODE_TO_OUT_CODE);
        //预报订单号
        map.put(FORECAST_ORDER_BIZ_ID,forecastOrderSDO.getOrderBizId());
        //设置 feature
        participateActivityRequest.setFeatures(map);

        //设置参加活动参数列表
        participateActivityRequest.setParticipateActivityInfoList(participateActivityInfoList);
        //列表为空，不要调用
        if (CollectionUtils.isEmpty(participateActivityInfoList)) {
            ParticipateInActivityResponse participateInActivityResponse=new ParticipateInActivityResponse();
            isNeedCallParticipateActivity[0] = false;
            return participateInActivityResponse;
        }
        Result<ParticipateInActivityResponse> participateInActivityResponseResult = activityWriteService.participateActivityExpand(participateActivityRequest);
        if (Objects.nonNull(participateInActivityResponseResult)
                && Objects.nonNull(participateInActivityResponseResult.getResult())
                && CollectionUtils.isNotEmpty(participateInActivityResponseResult.getResult().getParticipateActivityResponseList())) {

            if( participateInActivityResponseResult.isSuccess()){
                return participateInActivityResponseResult.getResult();
            }
        }
        return null;
    }

    /**
     * 更新成最新的活动版本号
     * @param activitySDOS 活动列表，经过分析后的活动列表
     * @param activityCode 活动 ID
     * @param activityTermId 活动项目 ID
     * @param version 活动版本号
     * @return 活动版本号
     */
    private Integer updateNewVersion(List<ActivitySDO> activitySDOS, String activityCode, String activityTermId,
                                     Integer version) {
        if (CollectionUtils.isEmpty(activitySDOS) || StringUtils.isBlank(activityCode)
                || StringUtils.isBlank(activityTermId)) {
            return version;
        }

        Map<String, ActivitySDO> activitySDOMap = activitySDOS.stream().collect(Collectors.toMap(
                sdo -> sdo.getActivityCode() + "_" + sdo.getActivityTermid(), Function.identity()));

        String key = activityCode + "_" + activityTermId;
        if (Objects.nonNull(activitySDOMap.get(key))) {
            return activitySDOMap.get(key).getVersion();
        }
        return version;
    }

    /**
     * 移除重复的子单请求参数
     * @param activityInfoRequestList 查询活动信息请求列表
     * @return
     */
    private List<ActivityInfoRequest> removeRepeatActivityInfoRequest(List<ActivityInfoRequest> activityInfoRequestList) {
        List<ActivityInfoRequest> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(activityInfoRequestList)) {
            return result;
        }

        Map<String, ActivityInfoRequest> map = new HashMap<>();
        for (ActivityInfoRequest infoRequest : activityInfoRequestList) {
            String key = infoRequest.getMainOrderId() + "_" + infoRequest.getSubOrderId();
            map.putIfAbsent(key, infoRequest);
        }

        return new ArrayList<>(map.values());
    }

    /**
     * 构造活动参加参数
     *
     * @param forecastOrderLineSDO
     * @param activitySDO
     * @return
     */

    @NotNull
    private ParticipateActivityInfoRequest buildParticipateActivityInfoRequest(ForecastOrderLineSDO forecastOrderLineSDO, ActivitySDO activitySDO,String sequenceNo) {
        ParticipateActivityInfoRequest participateActivityInfoRequest = new ParticipateActivityInfoRequest();
        participateActivityInfoRequest.setActivityId(activitySDO.getActivityCode());
        participateActivityInfoRequest.setClientId(this.forecastOrderSDO.getCustomerCode());
        participateActivityInfoRequest.setMainOrderId(forecastOrderLineSDO.getMainOrderId());
        participateActivityInfoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
        participateActivityInfoRequest.setOrderType(forecastOrderSDO.getOrderType());
        participateActivityInfoRequest.setDeliveryDate(forecastOrderSDO.getCustomerExpectTDate());
        participateActivityInfoRequest.setActivityUseTime(new Date());
        ParticipateActivityTermRequest participateActivityTermRequest = new ParticipateActivityTermRequest();
        participateActivityTermRequest.setActivityTermId(activitySDO.getActivityTermid());
        participateActivityTermRequest.setSpecialOfferPrice(activitySDO.getSpecialOfferPrice());
        participateActivityTermRequest.setCommonGroupFlag(activitySDO.getCommonGroupFlag());
        participateActivityInfoRequest.setSequenceNo(sequenceNo);
        Map<String,String> features=new HashMap<>();
        //预报订单号
        features.put(FORECAST_ORDER_BIZ_ID,forecastOrderSDO.getOrderBizId());
        //行号
        features.put(SERIAL_NUMBER,forecastOrderLineSDO.getSerialNumber());

        participateActivityInfoRequest.setFeatures(features);

        //原品信息
        ActivityItemInfo itemActivityItemInfo = new ActivityItemInfo();
        itemActivityItemInfo.setItemId(forecastOrderLineSDO.getScItemId());
        Integer itemQuantity = forecastOrderLineSDO.getPredictReplyAmount() == null ? Integer.parseInt(forecastOrderLineSDO.getQuantity()) :
                forecastOrderLineSDO.getPredictReplyAmount();
        itemActivityItemInfo.setItemQuantity(itemQuantity);
        itemActivityItemInfo.setItemName(forecastOrderLineSDO.getScItemTitle());
        itemActivityItemInfo.setItemPrice(Long.parseLong(String.valueOf(forecastOrderLineSDO.getUnitPrice() == null ? "0" : forecastOrderLineSDO.getUnitPrice())));
        itemActivityItemInfo.setSalesUnit(forecastOrderLineSDO.getSaleUnit());
        itemActivityItemInfo.setStockUnit(forecastOrderLineSDO.getInventoryUnit());
        participateActivityTermRequest.setItem(itemActivityItemInfo);
        participateActivityTermRequest.setVersion(activitySDO.getVersion());

        //赠品信息
        List<ActivityItemInfo> giftList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(activitySDO.getChooseGiftList())) {
            activitySDO.getChooseGiftList().forEach(giftSDO -> {
                ActivityItemInfo activityItemInfo = new ActivityItemInfo();
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setItemId(giftSDO.getScItemId());
                activityItemInfo.setItemName(giftSDO.getGiftName());
                activityItemInfo.setItemQuantity(giftSDO.getGiftNumber());
                activityItemInfo.setSalesUnit(giftSDO.getGiftUint());
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                giftList.add(activityItemInfo);
            });
        }

        participateActivityTermRequest.setGiftList(giftList);
        participateActivityInfoRequest.setParticipateActivityTermRequest(participateActivityTermRequest);
        return participateActivityInfoRequest;
    }

    public List<String> totalReplyNumber() {
        List<String> ids = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        forecastOrderLineSDOList.forEach(forecastOrderLineSDO -> {
            String id = String.valueOf(forecastOrderLineSDO.getId());
            ids.add(id);
        });
        return ids;
    }

    public boolean confirmForecastStatus() {
        /**
         * 修改订单状态  根据确认数量  修改累计回复数量  判断累计回复数量是否大于预保数量
         * 大于子订单状态变为已完成
         * 不大于子订单状态为部分回复
         *
         * 再根据主单的所有子单状态判断主订单的状态 并作修改
         */
        boolean isSuccess = true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            Integer actualTotalReplyAmount = forecastOrderLineSDO.getActualTotalReplyAmount();
            //当累计回复数量大于预保数量的时候状态为已完成 否则为部分回复
            if (actualTotalReplyAmount >= Integer.parseInt(forecastOrderLineSDO.getQuantity())) {
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.COMPLETED.getNumValue());
            } else {
                forecastOrderLineSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());

            }
            forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.CONFIRM_ED.getStatus());
            isSuccess = forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
            //添加到处理队列
            updateDealQueueStatus(forecastOrderLineSDO);
        }
        //获取主订单下所有的子订单
        ForecastOrderSDO forecastOrderSDO = forecastOrderLineQueryRepository.queryByOrderId(this.forecastOrderSDO);
        boolean isStatusTag = true;
        int isComTag = 0;
        int isWaitTag = 0;
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            if (ForecastLineStatusEnum.PARTIAL_REPLY.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                forecastOrderSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());
                isStatusTag = false;
            }
            if (ForecastLineStatusEnum.COMPLETED.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                //子订单有完成状态
                isComTag += 1;
            }
            if (ForecastLineStatusEnum.WAITING_FOR_REPLY.equals(ForecastLineStatusEnum.of(forecastOrderLineSDO.getStatus()))) {
                //子订单有待回复状态
                isWaitTag += 1;
            }
            if (isComTag > 0 && isWaitTag > 0) {
                forecastOrderSDO.setStatus(ForecastStatusEnum.PARTIAL_REPLY.getNumValue());
                isStatusTag = false;
            }
        }
        if (isStatusTag) {
            forecastOrderSDO.setStatus(ForecastStatusEnum.COMPLETED.getNumValue());
        }

        isSuccess = forecastOrderWriteRepository.modifyForecast(forecastOrderSDO);
        return isSuccess;
    }


    /**
     * 更新预报单
     * @return
     */
    public Boolean updateActivityForecast() {
        boolean isSuccess=true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.update(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public Boolean deleteActivityForecast() {
        boolean isSuccess=true;
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = this.forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            isSuccess = forecastOrderLineWriteRepository.updateForAnalysis(forecastOrderLineSDO);
        }
        return isSuccess;
    }

    public String summaryForecastOrder() {
        //创建调拨单
        AllocateOrderManualCreateRequest createRequest = new AllocateOrderManualCreateRequest();
        createRequest.setType("2");
        createRequest.setReturnOrder(false);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String format = sdf.format(this.forecastOrderSDO.getCustomerExpectTDate());
        createRequest.setExpectedDeliveryTime(format);
        //总部渠道编码 默认20
        createRequest.setSapChannel("20");
        //总部组织编码 默认6000
        createRequest.setSapSalesOrgId("6000");
        createRequest.setReceiveAreaId(forecastOrderSDO.getWareHouseCode());
        createRequest.setShipMethod(forecastOrderSDO.getTransportModeCode());
        createRequest.setCustomerAddress(forecastOrderSDO.getReceiveDetailAddress());
        createRequest.setIsDTC(false);
        createRequest.setApplyOrgId(forecastOrderSDO.getOrganizationCode());
        createRequest.setRemark("预报生成调拨单");
        Result<AllocateOrderResponse> createResult = allocateOrderWriteService.manualCreate(createRequest);
        if (createResult==null || !createResult.isSuccess() || createResult.getResult()==null){
            throw new RuntimeException("创建调拨主单失败");
        }
        String id = createResult.getResult().getId();
        String code = createResult.getResult().getCode();

        //保存调拨单明细
        AllocateOrderSaveRequest saveRequest = new AllocateOrderSaveRequest();
        saveRequest.setId(id);
        saveRequest.setCode(code);
        int num = 1;
        List<AllocateOrderScItemDetail> allocateOrderScItemDetails = new ArrayList<>();
        List<ForecastOrderLineSDO> forecastOrderLineSDOList = forecastOrderSDO.getForecastOrderLineSDOList();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderLineSDOList) {
            //设置货品信息
            AllocateOrderScItemDetail allocateOrderScItemDetail = new AllocateOrderScItemDetail();
            if (MapUtils.isNotEmpty(forecastOrderLineSDO.getFeatures())){
                Map features = forecastOrderLineSDO.getFeatures();
                allocateOrderScItemDetail.setScItemId((String)features.get("goodsCode"));
            }
            allocateOrderScItemDetail.setTitle(forecastOrderLineSDO.getScItemTitle());
            allocateOrderScItemDetail.setGoodsId(forecastOrderLineSDO.getScItemId());
            allocateOrderScItemDetail.setUnitPrice(BigDecimal.valueOf(forecastOrderLineSDO.getUnitPrice()));
            allocateOrderScItemDetail.setLineNo(String.valueOf(num++));
            allocateOrderScItemDetail.setApplyQuantity(forecastOrderLineSDO.getQuantity());
            allocateOrderScItemDetail.setConfirmedQuantity(forecastOrderLineSDO.getQuantity());
            allocateOrderScItemDetails.add(allocateOrderScItemDetail);
        }
        saveRequest.setAllocateOrderScItemDetails(allocateOrderScItemDetails);
        log.info("allocateOrderWriteService#saveRequest={}", JSON.toJSONString(saveRequest));
        Result<AllocateOrderSaveResponse> saveResult = allocateOrderWriteService.save(saveRequest);
        if (saveResult==null || !saveResult.isSuccess()){
            throw new RuntimeException("保存调拨单明细失败");
        }
        return code;
    }

    public ForecastOrderLineSDO getOrderLineFeatures(ForecastOrderLineSDO forecastOrderLineSDO,Integer qty) {
        // 活动价格备注字段
//        if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityPriceRemark()) && CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
//            return forecastOrderLineSDO;
//        }
        List<String> ids = new ArrayList<>(1);
        ids.add(String.valueOf(forecastOrderLineSDO.getId()));
        PageResult<List<ForecastOrderLineSDO>> result = forecastOrderLineQueryRepository.batchLoadList(ids);
        if (CollectionUtils.isEmpty(result.getContent())) {
            return forecastOrderLineSDO;
        }
        Map<String, Object> features = result.getContent().get(0).getFeatures();
        if (MapUtils.isEmpty(features)) {
            Map<String, Object> map = new HashMap<>();
            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityPriceRemark())) {
                map.put(ForecastConstants.ACTIVITY_PRICE_REMARK, forecastOrderLineSDO.getActivityPriceRemark());
            }
            if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
                map.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            }
            forecastOrderLineSDO.setFeatures(map);
        } else {
            if (StringUtils.isEmpty(forecastOrderLineSDO.getActivityPriceRemark())) {
                features.put(ForecastConstants.ACTIVITY_PRICE_REMARK, forecastOrderLineSDO.getActivityPriceRemark());
            }
            if (CollectionUtils.isNotEmpty(forecastOrderLineSDO.getSaleUnitList())) {
                features.put(ForecastConstants.SALE_UNIT_LIST, forecastOrderLineSDO.getSaleUnitList());
            }
            features.put(ForecastConstants.ACTIVITY_PRICE_REMARK, forecastOrderLineSDO.getActivityPriceRemark());
            forecastOrderLineSDO.setFeatures(features);
        }
        features.put(DISINTEGRATION_QTY,qty);
        log.info("编辑子单信息:" + JSONObject.toJSONString(forecastOrderLineSDO));
        return forecastOrderLineSDO;
    }
    private Map<String, Object> queryDailyInv(ForecastOrderSDO sdo, ForecastOrderLineSDO build) {
        HashMap<String, Object> stringObjectHashMap = new HashMap<>();

        String organizationCode = sdo.getOrganizationCode();
        String channelCode = sdo.getChannelCode();
        String departmentCode = sdo.getDepartmentCode();
        String salesmanCode = sdo.getSalesmanCode();
        String wareHouseCode = sdo.getWareHouseCode();

        QueryAllotRequest queryAllotRequest = new QueryAllotRequest();
        queryAllotRequest.setOrganizationCode(organizationCode);
        queryAllotRequest.setChannelCode(channelCode);
        queryAllotRequest.setDepartmentCode(departmentCode);
        queryAllotRequest.setSalesmanCode(salesmanCode);
        queryAllotRequest.setWarehouseCode(wareHouseCode);
        queryAllotRequest.setScItemId(build.getScItemId());
        Result<QueryAllotResponse> result = inventoryAllotQueryService.queryAllot(queryAllotRequest);
        stringObjectHashMap.put("limitSwitch",false);
        if (Objects.nonNull(result)&&Objects.nonNull(result.getResult())){
            stringObjectHashMap.put("limitSwitch",result.getResult().getMainLimitSwitch());
            stringObjectHashMap.put("dailyInventory",result.getResult().getRemainingQuantity());
        }
        return stringObjectHashMap;
    }
}
